<script setup lang="ts" name="DataInputOutput">
import { mapState } from 'pinia'
import { useModelerStore } from '@/store/bpmnProcess/modelerStore'
import DataInputOutputDrawer from './components/DataInputOutputDrawer.vue'
import useMessageBox from '@/hooks/useMessageBox'
import {
  areInputParametersSupported,
  areOutputParametersSupported,
  getInputParameters,
  addInputParameter,
  editInputParameter,
  removeInputParameters,
  getOutputParameters,
  addOutputParameter,
  editOutputParameter,
  removeOutputParameters,
  getInputOutputType,
  getAssignmentTypeObject
} from '../../../utils/dataInputOutput'
import {
  areConnectorsSupported,
  getConnectorInput,
  addConnectorInputParameter,
  editConnectorInputParameter,
  removeConnectorInputParameters,
  getConnectorOutput,
  addConnectorOutputParameter,
  editConnectorOutputParameter,
  removeConnectorOutputParameters
} from '../../../utils/connectorInputOutput'
import { cloneDeep } from 'lodash-es'
import EventEmitter from '@/utils/EventEmitter'

const { messageBox } = useMessageBox()

const props = defineProps({
  type: {
    type: String,
    default: ''
  },
  isConnector: {
    type: Boolean,
    default: false
  }
})

const mapStates = computed(() => {
  return mapState(useModelerStore, ['getActive'])
})

const DataInputOutputDrawerRef = ref(null)

const assignmentTypeObject = ref(null)
let dataParameters = markRaw([])
const dataParametersList = ref([])
const editIndex = ref(-1)

const add = () => {
  editIndex.value = -1
  const res = {
    type: props.type,
    isConnector: props.isConnector
  }
  DataInputOutputDrawerRef.value.showDrawer(res)
}
const edit = (row, index) => {
  editIndex.value = index
  const res = {
    type: props.type,
    isConnector: props.isConnector,
    row
  }
  DataInputOutputDrawerRef.value.showDrawer(res)
}
const deleteRow = (index) => {
  const typeText = props.type === 'InputParameter' ? '输入' : '输出'
  const cateText = props.isConnector ? '连接器' : ''
  const msg = '确认<span>删除</span>该' + cateText + typeText + '数据吗？'
  const msgTips = ''
  messageBox('danger', true, msg, msgTips, () => {
    if (props.isConnector) {
      if (props.type === 'InputParameter') {
        removeConnectorInputParameters(mapStates.value.getActive(), dataParameters[index])
      } else {
        removeConnectorOutputParameters(mapStates.value.getActive(), dataParameters[index])
      }
    } else {
      if (props.type === 'InputParameter') {
        removeInputParameters(mapStates.value.getActive(), dataParameters[index])
      } else {
        removeOutputParameters(mapStates.value.getActive(), dataParameters[index])
      }
    }
  })
}

const dataInputOutputChange = (v) => {
  if (props.isConnector) {
    if (props.type === 'InputParameter') {
      if (editIndex.value === -1) {
        addConnectorInputParameter(mapStates.value.getActive(), v)
      } else {
        editConnectorInputParameter(mapStates.value.getActive(), v, editIndex.value)
      }
    } else {
      if (editIndex.value === -1) {
        addConnectorOutputParameter(mapStates.value.getActive(), v)
      } else {
        editConnectorOutputParameter(mapStates.value.getActive(), v, editIndex.value)
      }
    }
  } else {
    if (props.type === 'InputParameter') {
      if (editIndex.value === -1) {
        addInputParameter(mapStates.value.getActive(), v)
      } else {
        editInputParameter(mapStates.value.getActive(), v, editIndex.value)
      }
    } else {
      if (editIndex.value === -1) {
        addOutputParameter(mapStates.value.getActive(), v)
      } else {
        editOutputParameter(mapStates.value.getActive(), v, editIndex.value)
      }
    }
  }
}

const initData = () => {
  assignmentTypeObject.value = getAssignmentTypeObject()
  if (props.isConnector) {
    if (props.type === 'InputParameter') {
      dataParameters = markRaw(getConnectorInput(mapStates.value.getActive()))
    } else {
      dataParameters = markRaw(getConnectorOutput(mapStates.value.getActive()))
    }
  } else {
    if (props.type === 'InputParameter') {
      dataParameters = markRaw(getInputParameters(mapStates.value.getActive()))
    } else {
      dataParameters = markRaw(getOutputParameters(mapStates.value.getActive()))
    }
  }
  dataParametersList.value = cloneDeep(dataParameters)
  if (dataParametersList.value.length > 0) {
    dataParametersList.value.forEach((item) => {
      item.type = getInputOutputType(item)
    })
  }
  console.log(dataParameters, '数据参数')
}

const getCollapseItemName = () => {
  let res = props.type
  if (props.isConnector) {
    res = 'connector-' + props.type
  }
  return res
}

const getCollapseHeaderTitle = () => {
  let res = ''
  if (props.isConnector) {
    if (props.type === 'InputParameter') {
      res = '连接器输入'
    } else {
      res = '连接器输出'
    }
  } else {
    if (props.type === 'InputParameter') {
      res = '输入'
    } else {
      res = '输出'
    }
  }
  return res
}

const getAddButtonText = () => {
  let res = props.type
  if (props.isConnector) {
    if (props.type === 'InputParameter') {
      res = '添加连接器输入数据'
    } else {
      res = '添加连接器输出数据'
    }
  } else {
    if (props.type === 'InputParameter') {
      res = '添加输入数据'
    } else {
      res = '添加输出数据'
    }
  }
  return res
}

const eventEmitterListener = () => {
  if (!props.isConnector && props.type === 'InputParameter' && areInputParametersSupported(mapStates.value.getActive()) || !props.isConnector && props.type === 'OutputParameter' && areOutputParametersSupported(mapStates.value.getActive()) || props.isConnector && areConnectorsSupported(mapStates.value.getActive())) {
    initData()
  }
}

onBeforeUnmount(() => {
  EventEmitter.removeListener('element-update', eventEmitterListener)
})

onMounted(() => {
  initData()
  EventEmitter.on('element-update', eventEmitterListener)
})
</script>

<template>
  <el-collapse-item :name="getCollapseItemName()">
    <template #title>
      <div class="collapse-header">
        <svg-icon v-if="!props.isConnector && props.type === 'InputParameter'" icon="ri:login-box-fill"></svg-icon>
        <svg-icon v-if="!props.isConnector && props.type === 'OutputParameter'" icon="ri:logout-box-r-fill"></svg-icon>
        <svg-icon v-if="props.isConnector && props.type === 'InputParameter'" icon="ri:login-circle-fill"></svg-icon>
        <svg-icon v-if="props.isConnector && props.type === 'OutputParameter'" icon="ri:logout-circle-r-fill"></svg-icon>
        <h2>{{ getCollapseHeaderTitle() }}</h2>
        <el-button type="primary" size="small" plain circle>{{ dataParametersList.length }}</el-button>
      </div>
    </template>
    <el-form-item>
      <el-table :data="dataParametersList" border>
        <el-table-column type="index" label="序号" width="60" />
        <el-table-column prop="name" :label="props.type === 'InputParameter' ? '局部变量名' : '流程变量名'" />
        <el-table-column prop="type" label="赋值类型" show-overflow-tooltip :formatter="row => assignmentTypeObject[row.type]" />
        <el-table-column prop="operate" label="操作" width="110" align="center">
          <template #default="scope">
            <el-button type="primary" icon="Edit" circle @click="edit(scope.row, scope.$index)"></el-button>
            <el-button type="danger" icon="Delete" circle @click="deleteRow(scope.$index)"></el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-button class="add" type="primary" icon="Plus" @click="add">{{ getAddButtonText() }}</el-button>
    </el-form-item>
    <DataInputOutputDrawer ref="DataInputOutputDrawerRef" @save="dataInputOutputChange"></DataInputOutputDrawer>
  </el-collapse-item>
</template>

<style scoped lang="scss">
.el-collapse-item {
  :deep(.el-collapse-item__header) {

    .collapse-header {
      display: flex;
      flex: 1;
      align-items: center;
      padding: 0 12px;

      .el-icon {
        margin-right: 6px;
        font-size: 20px !important;
      }

      h2 {
        display: flex;
        flex: 1;
        justify-content: flex-start;
        font-weight: bold;
        font-size: 14px;
      }

      .el-button {
        margin-left: 12px;
      }
    }

    .el-icon {
      font-size: 18px;
    }
  }

  :deep(.el-collapse-item__content) {
    padding-right: 12px;
    padding-bottom: 12px;
    padding-left: 12px;
  }
}

.el-form-item {
  :deep(.el-form-item__content) {
    margin-left: 0 !important;

    .el-button.add {
      width: 100%;
      margin: 12px 0 0;
    }
  }
}
</style>
